/**
 * Project: apollo-base-tools
 * 
 * File Created at 2017年7月24日
 * 
 * Copyright 2015-2016 dx.com Croporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * DongXue software Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with dx.com.
 */
package org.apollo.swing.commons;

import java.awt.event.ActionEvent;
import java.lang.reflect.Method;

import javax.swing.AbstractAction;
import javax.swing.Icon;

/** 
* @ClassName: DynamicAction 
* @Description: TODO(这里用一句话描述这个类的作用) 
* @author wuzhenfang(wzfbj2008@163.com)
* @date 2017年7月24日 下午3:33:34 
* @version V1.0 
*/
public class DynamicAction extends AbstractAction {

	private static final long serialVersionUID = -3415801202691755222L;

	private Method method = null;
	private final String methodName;
	private final Object target;
	private final Object[] args;

	public DynamicAction(Object target, String methodName, Object... args) {
		this(null, null, target, methodName, args);
	}

	public DynamicAction(String name, Object target, String methodName, Object... args) {
		this(name, null, target, methodName, args);
	}

	public DynamicAction(String name, Icon icon, Object target, String methodName, Object... args) {
		super(name, icon);
		if ((target == null) || (methodName == null)) {
			throw new IllegalArgumentException("Target and method name must be non-null");
		}
		this.target = target;
		this.methodName = methodName;
		this.args = args;
	}

	public void actionPerformed(ActionEvent e) {
		Class klass = null;
		Object obj = null;
		if ((this.target instanceof Class)) {
			klass = (Class) this.target;
		} else {
			klass = this.target.getClass();
			obj = this.target;
		}
		try {
			if (this.method == null) {
				Class[] argClasses = null;
				if ((this.args != null) && (this.args.length > 0)) {
					argClasses = new Class[this.args.length];
					for (int i = 0; i < this.args.length; i++) {
						argClasses[i] = (this.args[i] == null ? null : this.args[i].getClass());
					}
				} else {
					argClasses = new Class[0];
				}
				this.method = ClassUtils.getAnyMethod(klass, this.methodName, argClasses);
			}
			if (this.method != null) {
				boolean oldAccessible = true;
				if (oldAccessible != this.method.isAccessible()) {
					this.method.setAccessible(true);
				}
				try {
					if (this.args != null) {
						this.method.invoke(obj, this.args);
					} else {
						this.method.invoke(obj, new Object[0]);
					}
				} finally {
					if (!oldAccessible) {
						this.method.setAccessible(oldAccessible);
					}
				}
			}
		} catch (Throwable exception) {
//			if (Application.getInstance() != null) {
//				Application.getInstance().uncaughtException(exception);
//			} else {
//				throw new RuntimeException(exception);
//			}
		}
	}
}
